// 协议制定
// 1.协议制定好
// 2.根据协议对收到的消息做出响应
#include <iostream>
#include <string>
#include <cstring>
#include<stdlib.h>
#include<unistd.h>
#include <sys/types.h>
#include <sys/socket.h>
//#include <json.h>

#define LINE " "
#define LINE_LEN strlen(LINE)
#define SEM "\r\n"
#define SEM_LEN strlen(SEM)

using namespace std;

enum
{
    OK=0,
    DIV_ZERO,
    MOD_ZERO,
    OP_ERROR

};
string enlength(const string&text)
{   string length;
    string prelen=to_string(text.size());
    length+=prelen;
    length+=SEM;
    length+=text;

   return length;
}

bool delength(const string &package,string*text)//利用输出型参数实现
{      auto pos =package.find(SEM);
       if(pos==string::npos) return false;
       int length=stoi(package.substr(0,pos));
       *text=package.substr(pos+SEM_LEN,length);
        return true;
}

class Request
{
public:
    Request() : x_(0), y_(0), op_(0)
    {
    }
    Request(int x, int y, char op) : x_(x), y_(y), op_(op)
    {
    }
    bool serialize(string *out) // 将结构化消息进行变成字符串，序列化
    {
//#ifdef MYSELF
        string x = to_string(x_);
        string y = to_string(y_);
        *out += x;
        *out += LINE;
        *out += op_;
        *out += LINE;
        *out += y;
// #else
//        Json::Value root;
//        root["first"]=x_;
//        root["second"]=y_;
//        root["oper"]=op_;
//        Json::FastWriter writer;
//        *out=writer.write(root);


// #endif
        return true;
    }
    bool deserialize(const string &in) // 将字符串变为结构化，反序列化
    {  
//#ifdef MYSELF
        auto left=in.find(LINE);
        auto right=in.rfind(LINE);//从右边开始找
        if(left==right) return false;
        if(left==string::npos||right==string::npos) return false;
        string x=in.substr(0,left);
        string y=in.substr(right+LINE_LEN);
        if (x.empty() || y.empty())
            return false;
     
        x_=stoi(x);
        y_=stoi(y);
        op_=in[left+LINE_LEN];//找单个字符，直接用下标寻找

// #else
//        Json::Value root;
//        Json::Reader reader;
//        reader.parse(in.root);
//        x_=root["first"].asInt();
//        y_=root["second"].asInt();
//        op_=root["oper"].asInt();
// #endif
     return true;

    }

public:
    int x_;
    int y_;
    char op_;
};

class Response
{public:
    Response():exitcode(0),result(0){}
    Response(int exitcode_,int result_):exitcode(exitcode_),result(result_){}
    bool serialize(string *out)
    {
//#ifdef MYSELE
         string x = to_string(exitcode);
        string y = to_string(result);
        *out += x;
        *out += LINE;
        *out += y;
// #else
//         Json::Value root;
//         root["exitcode"]=exitcode;
//         root["result"]=result;
//         Json::FastFwriter writer;
//         *out=writer.write(root);
// #endif
        return true;
    }
     bool deserialize(const string &in) // 将字符串变为结构化，反序列化
    {   
//#ifdef MYSELE
        auto mid=in.find(LINE);
        if(mid==string::npos) return false;
        string x=in.substr(0,mid);
        string y=in.substr(mid+LINE_LEN);
          if (x.empty() || y.empty())//为了防止in里没用需要的数据,没有拿到结果
            return false;
        exitcode=stoi(x);
        result=stoi(y);
        
// #else
//           Json:: Value root;
//           Json:: read reader;
//           reader.parse(in.root);
//           exitcode=root["exitcode"].asInt;
//           result=root["result"].asInt;

        return true;
    }
    public:
    int exitcode;
    int result;
};

bool recvpackage(int sock,string &inbuffer,string *text)//inbuffer用于记录
{ //1.读传递过来的数据
     
   char buffer[1024];
   while(true)//为了防止没读完数据，重新读
   {
   ssize_t n=recv(sock,buffer,sizeof(buffer),0);//读传递的数据
   if(n>0)//n是读到的长度
   { buffer[n]=0;
     inbuffer=buffer;
     auto pos=inbuffer.find(SEM);
    string text_len_string=inbuffer.substr(0,pos);
    int text_len=text_len_string.size();
    int all_len=text_len_string.size()+text_len+2*SEM_LEN;//为了知道有没有读取到一个完整的信息的大小
     std::cout << "处理前#inbuffer: \n" << inbuffer << std::endl;
     if(inbuffer.size()<all_len)//说明读取不完整，需要重新读取
     {std::cout << "你输入的消息，没有严格遵守我们的协议，正在等待后续的内容, continue" << std::endl;
                continue;

     }
    *text=inbuffer.substr(0,all_len);//获得完整的内容包括前缀
    inbuffer.erase(0,all_len);//删除读完的内容
     std::cout << "处理后#inbuffer:\n " << inbuffer << std::endl;
      break;
   }
   else
   {
    return false;
   }

   }
  //2.根据数据的前缀，分离出具体的信息，如何分离？先找第一个分隔符，截取字符串[0,分割符位置）
  //3.传给输出型参数
    
  return true;
}